import { UpOutlined, SendOutlined } from '@ant-design/icons'
import { truthy, formatDate } from '@gnlab/utils'
import { Tooltip, Tag } from 'antd'
import c from 'classnames'
import flatMap from 'lodash/flatMap'
import  defaultAvatar  from '@/desktop/assets/avatar.jpg'
import { formatTextContent } from '@/desktop/views/chat/utils'
import services from '@/services'
import type { TextRecord, MatchedHistory } from '@/services/contact-chat'
import { makeContactIdByConversationId } from '@/services/contacts'
import './match.module.less'

export function Match(props: {
  match: MatchedHistory
  keyword: string // 当前搜索关键词
  focusingRecord: TextRecord | null // 当前正查看哪条聊天记录的详情
  focusRecord: (record: TextRecord) => void // 查看此聊天记录的详情
  goContact: (id: string) => void // 结束搜索，跳转到与此联系人的聊天
}) {
  const { match, keyword, focusingRecord, focusRecord, goContact } = props

  const contactId = makeContactIdByConversationId(match.wxid, match.conversationId)
  const contact = truthy(contactId)
    ? services.contacts.getById(contactId) ?? {
        id: contactId,
        avatar: '',
        name: match.conversationId,
      }
    : null
  useEffect(() => {
    // 若 contact 未出现在联系人列表里，尝试加载其信息
    if (truthy(contactId) && !services.contacts.getById(contactId)) {
      void services.contacts.loadInfo({ id: contactId })
    }
  }, [contactId])

  const [collapse, setCollapse] = useState(false)

  // ==================================

  if (!contact) return null

  return <div styleName={c('match', collapse && 'collapsed')}>
    <header onClick={() => setCollapse(!collapse)}>
      <img styleName="avatar" src={contact.avatar || defaultAvatar} />
      <div styleName="name">{contact.name}</div>
      <Tag styleName="count">{match.records.length}</Tag>
      <Tooltip title="前往聊天" color="blue">
        <SendOutlined
          onClick={e => {
            e.stopPropagation()
            goContact(contact.id)
          }}
        />
      </Tooltip>
      <UpOutlined styleName="collapse" />
    </header>

    {!collapse ? (
      <div styleName="records">
        {match.records.map(record => <Record
          key={record.id}
          record={record}
          keyword={keyword}
          focusing={focusingRecord === record}
          focusRecord={focusRecord}
        />)}
      </div>
    ) : null}
  </div>
}

function Record(props: {
  record: TextRecord
  keyword: string
  focusing: boolean
  focusRecord: (record: TextRecord) => void
}) {
  const { record, keyword, focusing, focusRecord } = props
  return <div
    styleName={c('record', focusing && 'focusing')}
    onClick={focusing ? undefined : () => focusRecord(record)}
  >
    <div styleName="text">{formatText(record.content.text, keyword)}</div>
    <div styleName="date">{formatDate(record.timestamp, { short: true, simple: false })}</div>
  </div>
}

function formatText(text: string, keyword: string) {
  return formatTextContent(cutToKeyword(text, keyword), nodes => highlightKeyword(nodes, keyword))
}

// 截取掉关键词前面太多的其他字符，保证关键词能显示出来
function cutToKeyword(text: string, keyword: string) {
  const index = text.indexOf(keyword)
  if (index > 10) text = '...' + text.slice(index - 10)
  return text
}

// 高亮关键词
function highlightKeyword(nodes: (string | JSX.Element)[], keyword: string) {
  return flatMap(nodes, (node, i) => {
    if (typeof node !== 'string') return [node]
    const split = node.split(keyword)
    if (split.length === 1) return split

    const highlight = (key: string) => <span styleName="highlight" key={key}>
      {keyword}
    </span>
    const formatted = flatMap(split, (item, j) => {
      if (j === split.length - 1) return [item]
      return [item, highlight(`high-${i}-${j}`)]
    })

    return formatted
  })
}
